package problems.daily;

/**
 * 641. 设计循环双端队列
 * <p>https://leetcode.cn/problems/design-circular-deque</p>
 * <p>可参考：{@link DT622.MyCircularQueue}</p>
 * <p></p>
 * @author habitplus
 * @since 2022/8/15 08:46
 */
public class DT641 {


    /**
     * Your MyCircularDeque object will be instantiated and called as such:<br>
     * MyCircularDeque obj = new MyCircularDeque(k);<br>
     * boolean param_1 = obj.insertFront(value);<br>
     * boolean param_2 = obj.insertLast(value);<br>
     * boolean param_3 = obj.deleteFront();<br>
     * boolean param_4 = obj.deleteLast();<br>
     * int param_5 = obj.getFront();<br>
     * int param_6 = obj.getRear();<br>
     * boolean param_7 = obj.isEmpty();<br>
     * boolean param_8 = obj.isFull();
     */
    class MyCircularDeque {
        // 存储数据
        final int[] data;
        // 指向队首元素
        int front;
        // 指向队尾的下一个元素
        int tail;
        // 容量 = 实际存储容量 + 1
        int sz;

        public MyCircularDeque(int k) {
            sz = k + 1;
            front = tail = 0;
            data = new int[sz];
        }

        public boolean insertFront(int value) {
            if (isFull()) return false;
            front = (front - 1 + sz) % sz;
            data[front] = value;
            return true;
        }

        public boolean insertLast(int value) {
            if (isFull()) return false;
            data[tail] = value;
            tail = (tail + 1) % sz;
            return true;
        }

        public boolean deleteFront() {
            if (isEmpty()) return false;
            front = (front + 1) % sz;
            return true;
        }

        public boolean deleteLast() {
            if (isEmpty()) return false;
            tail = (tail - 1 + sz) % sz;
            return true;
        }
        public int getFront() {
            return isEmpty() ? -1 : data[front];
        }

        public int getRear() {
            return isEmpty() ? -1 : data[(tail - 1 + sz) % sz];
        }

        public boolean isEmpty() {
            return tail == front;
        }

        public boolean isFull() {
            return (tail + 1) % sz == front;
        }
    }
}
